<?php
namespace hangpu8\hpcms\service;

use hangpu8\hpcms\model\AuthRule as ModelAuthRule;
use hangpu8\hpcms\Utils\Data;
use think\Exception;

class AuthRule
{
    private $db;

    /**
     * 构造函数
     */
    public function __construct()
    {
        $this->db = new ModelAuthRule;
    }

    /**
     * 获取列表数据
     *
     * @param array $where
     * @param string $order
     * @param string $field
     * @param integer $limit
     * @return array
     */
    public function getlist($where = [],$order = 'sort asc',$field = '*',$limit = 300) : array
    {
        // 类型：form表单页，tabForm选项卡表单，list表格页，treeTable树表格，component自定义组件，router纯接口，structure构建代码
        $type = [
            'form'              => '表单页',
            'tabForm'           => '选项卡',
            'list'              => '表格页',
            'treeTable'         => '树表格',
            'router'            => '纯接口',
            'component'         => '远程组件',
            'structure'         => '代码构建',
        ];
        // 显示与隐藏
        $status = ['隐藏','显示'];
        $map = [];
        if ($where)
        {
            $map = $where;
        }
        $list = $this->db->where($map)
        ->order($order)
        ->field($field)
        ->paginate($limit)
        ->each(function($item)use($status,$type){
            $bool = $this->db->where(['pid'=> $item['path']])->count();
            $item['hasChildren'] = $bool ? true : false;
            if (isset($item['show']))
            {
                $item['show_text'] = $status[$item['show']];
            }
            if (isset($item['type']))
            {
                $item['type_text'] = $type[$item['type']];
            }
            return $item;
        })->toArray();
        return $list;
    }
    
    /**
     * 创建数据
     *
     * @param array $post
     * @return bool
     */
    public function create(array $post) : bool
    {
        $data['pid'] = is_array($post['pid']) ? end($post['pid']) : $post['pid'];
        $data['title'] = $post['title'];
        $data['path'] = $post['path'];
        $data['desc'] = $post['desc'];
        $data['method'] = implode(',',$post['method']);
        $data['type'] = $post['type'];
        $data['version'] = $post['version'];
        $data['icon'] = $post['icon'];
        $data['show'] = $post['show'];
        $data['sort'] = $post['sort'];
        if ($this->db->save($data))
        {
            return true;
        }else{
            throw new Exception("添加数据失败",404);
        }
    }
    
    /**
     * 修改数据
     *
     * @param array $post
     * @param array $map
     * @return boolean
     */
    public function saveUpdate(array $post,array $map) : bool
    {
        try {
            $data['pid'] = is_array($post['pid']) ? end($post['pid']) : $post['pid'];
            $data['title'] = $post['title'];
            $data['path'] = $post['path'];
            $data['desc'] = $post['desc'];
            $data['method'] = is_array($post['method']) ? implode(',',$post['method']) : $post['method'];
            $data['type'] = $post['type'];
            $data['version'] = $post['version'];
            $data['icon'] = $post['icon'];
            $data['show'] = $post['show'];
            $data['sort'] = $post['sort'];
            return $this->db->where($map)->save($data);;
        } catch (\Throwable $e) {
            throw new Exception($e->getMessage(),404);
        }
    }

    /**
     * 删除数据
     *
     * @param [type] $path
     * @return void
     */
    public function del($path)
    {
        try {
            $model = ModelAuthRule::where(['path'=> $path])->find();
            // 软删除
            return $model->delete();
        } catch (\Throwable $e) {
            throw new Exception($e->getMessage(),404);
        }
    }

    /**
     * 获取表单数据
     *
     * @param array $where
     * @return array
     */
    public function getForm(array $where) : array
    {
        $data = $this->db->where($where)->find();
        if ($data)
        {
            $data = $data->toArray();
            $method = strstr($data['method'], ',') ? explode(',',$data['method']) : [$data['method']];
            $data['method'] = $method;
        }
        return $data;
    }

    /**
     * 获取路由列表数据
     *
     * @return array
     */
    public function getRoutes() : array
    {
        $list = $this->db->limit(1000)->select()->toArray();
        $i = 0;
        foreach ($list as $value)
        {
            list($module,$controller,$action) = explode("/",$value['path']);
            $controller = ucfirst($controller);
            $namespace = "";
            $router = "";
            if ($module == "hangpu8")
            {
                if (empty($value['version'])) {
                    $router = "/{$module}/{$controller}/{$action}";
                    $namespace = "\\{$module}\\hpcms\\controller\\{$controller}@{$action}";
                }else{
                    $router = "/{$module}/{$value['version']}.{$controller}/{$action}";
                    $namespace = "\\{$module}\\hpcms\\controller\\{$value['version']}\\{$controller}@{$action}";
                }
            }else{
                if (empty($value['version'])) {
                    $router = "/{$module}/{$controller}/{$action}";
                    $namespace = "app\\{$module}\\controller\\{$controller}@{$action}";
                }else{
                    $router = "/{$module}/{$value['version']}.{$controller}/{$action}";
                    $namespace = "app\\{$module}\\controller\\{$value['version']}\\{$controller}@{$action}";
                }
            }
            // 拆分多种请求路由
            $methods = explode(',',$value['method']);
            if (count($methods) > 1)
            {
                foreach ($methods as $value2)
                {
                    $item['router'] = $router;
                    $item['method'] = strtolower($value2);
                    $item['namespace'] = $namespace;
                    $item['version'] = $value['version'];
                    $routes[$i] = $item;
                    $i++;
                }
            }else{
                $item['router'] = $router;
                $item['method'] = strtolower($value['method']);
                $item['namespace'] = $namespace;
                $item['version'] = $value['version'];
                $routes[$i] = $item;
            }
            $i++;
        }
        return $routes;
    }

    /**
     * 获取表单所需要数据
     *
     * @return void
     */
    public function getFormData()
    {
        $methods = [
            [
                'label'     => 'GET',
                'value'     => 'GET',
            ],
            [
                'label'     => 'POST',
                'value'     => 'POST',
            ],
            [
                'label'     => 'PUT',
                'value'     => 'PUT',
            ],
            [
                'label'     => 'DELETE',
                'value'     => 'DELETE',
            ],
        ];
        $data['methods'] = $methods;
        // 类型：form表单页，tabForm选项卡表单，list表格页，treeTable树表格，component自定义组件，router纯接口，structure构建代码
        $type = [
            [
                'label'     => '表单页',
                'value'     => 'form',
            ],
            [
                'label'     => '选项卡',
                'value'     => 'tabForm',
            ],
            [
                'label'     => '表格页',
                'value'     => 'list',
            ],
            [
                'label'     => '树表格',
                'value'     => 'treeTable',
            ],
            [
                'label'     => '纯接口',
                'value'     => 'router',
            ],
            [
                'label'     => '远程组件',
                'value'     => 'component',
            ],
        ];
        $data['type'] = $type;
        $authRuleModel = new \hangpu8\hpcms\service\AuthRule;
        $parentList = $authRuleModel->getlist([]);
        $parent_level = Data::channelLevel($parentList['data'],'','','path','pid');
        $parents = $this->getChildrenOptions($parent_level);
        $parent = $parents;
        $data['parent'] = $parent;
        $show = [
            [
                'label'     => '隐藏',
                'value'     => 0,
            ],
            [
                'label'     => '显示',
                'value'     => 1,
            ],
        ];
        $data['show'] = $show;
        return $data;
    }

    /**
     * 递归拼接select数据
     *
     * @param array $data
     * @return void
     */
    private function getChildrenOptions(array $data)
    {
        $list = [];
        $i = 0;
        foreach ($data as $value)
        {
            $list[$i]['label'] = $value['title'];
            $list[$i]['value'] = $value['path'];
            if ($value['_data'])
            {
                $list[$i]['children'] = $this->getChildrenOptions($value['_data']);
            }
            $i++;
        }
        return $list;
    }
}